package thoven.achievement.net.ideapluginachievement.listener

import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.event.DocumentEvent
import com.intellij.openapi.editor.event.DocumentListener
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import thoven.achievement.net.ideapluginachievement.service.CodeStatsService
import thoven.achievement.net.ideapluginachievement.util.LanguageDetector

/**
 * 文档变更监听器
 * 用于跟踪代码行数变化
 */
class DocumentChangeListener(private val project: Project) : DocumentListener {
    
    private val LOG = logger<DocumentChangeListener>()
    
    override fun documentChanged(event: DocumentEvent) {
        try {
            val document = event.document
            val file = FileDocumentManager.getInstance().getFile(document) ?: return
            
            // 检查是否是代码文件
            if (!LanguageDetector.isCodeFile(file)) {
                return
            }
            
            // 计算新增和删除的行数
            val oldText = event.oldFragment.toString()
            val newText = event.newFragment.toString()
            
            val oldLineCount = countLines(oldText)
            val newLineCount = countLines(newText)
            
            val addedLines = maxOf(0, newLineCount - oldLineCount)
            val deletedLines = maxOf(0, oldLineCount - newLineCount)
            
            // 只有当有实际变更时才记录
            if (addedLines > 0 || deletedLines > 0) {
                val codeStatsService = CodeStatsService.getInstance(project)
                codeStatsService.recordCodeChange(file, addedLines, deletedLines)
                
                LOG.debug("代码变更: 文件=${file.name}, 新增=$addedLines, 删除=$deletedLines")
                
                // 检测特殊操作
                detectSpecialActions(newText, codeStatsService)
                
                // 检测文件行数（用于"细思极恐"成就）
                val totalLines = document.lineCount
                codeStatsService.recordMaxFileLines(totalLines)
            }
        } catch (e: Exception) {
            LOG.error("处理文档变更事件时出错", e)
        }
    }
    
    /**
     * 计算文本中的行数
     */
    private fun countLines(text: String): Int {
        if (text.isEmpty()) return 0
        
        var count = 1
        for (char in text) {
            if (char == '\n') {
                count++
            }
        }
        return count
    }
    
    /**
     * 检测特殊操作（用于解锁趣味成就）
     */
    private fun detectSpecialActions(text: String, codeStatsService: CodeStatsService) {
        // 检测 TODO/FIXME 注释
        if (text.contains("TODO", ignoreCase = true) || text.contains("FIXME", ignoreCase = true)) {
            codeStatsService.recordTodoFixme()
        }
        
        // 检测 console.log / print / System.out.println
        if (text.contains("console.log") || 
            text.contains("System.out.println") || 
            text.contains("print(") ||
            text.contains("println(") ||
            text.contains("console.error") ||
            text.contains("console.warn")) {
            codeStatsService.recordConsoleLog()
        }
        
        // 检测社死注释（包含尴尬或羞耻内容的注释）
        detectSocialDeathComments(text, codeStatsService)
        
        // 检测复杂或无语的代码模式
        detectComplexPatterns(text, codeStatsService)
        
        // 检测紧急修复模式
        detectEmergencyFix(text, codeStatsService)
    }
    
    /**
     * 检测社死注释
     */
    private fun detectSocialDeathComments(text: String, codeStatsService: CodeStatsService) {
        val socialDeathKeywords = listOf(
            "我也不知道为什么", "别问我", "这是什么鬼", "我写的什么垃圾",
            "我佛了", "要疯了", "救命", "妈的", "wtf", "shit", "fuck",
            "老子", "爷爷", "祖宗", "我去", "卧槽", "艹", "草",
            "看不懂就别看", "能跑就行", "反正能用", "先这样吧",
            "改天再说", "有空再改", "懒得改了", "爱咋咋地"
        )
        
        val lowerText = text.lowercase()
        if (socialDeathKeywords.any { keyword -> 
            lowerText.contains(keyword.lowercase()) && 
            (lowerText.contains("//") || lowerText.contains("/*") || lowerText.contains("#"))
        }) {
            codeStatsService.recordSocialDeathComment()
        }
    }
    
    /**
     * 检测复杂或让人无语的代码模式
     */
    private fun detectComplexPatterns(text: String, codeStatsService: CodeStatsService) {
        // 检测深层嵌套
        val braceCount = text.count { it == '{' }
        if (braceCount >= 5) {
            codeStatsService.recordComplexPattern()
        }
        
        // 检测超长行
        val lines = text.split('\n')
        if (lines.any { it.length > 200 }) {
            codeStatsService.recordComplexPattern()
        }
        
        // 检测让人无语的模式
        val annoyingPatterns = listOf(
            "if (true)", "if (false)", "while (true)", 
            "catch (Exception e) {}", "catch (...) {}",
            "// TODO: 实现这个功能", "// FIXME: 修复这个bug",
            "System.exit", "Thread.sleep(99999)",
            "var a, b, c, d, e, f, g, h", // 一堆单字母变量
            "return null;", "return undefined;",
            "eval(", "exec("
        )
        
        if (annoyingPatterns.any { pattern -> text.contains(pattern, ignoreCase = true) }) {
            codeStatsService.recordComplexPattern()
        }
    }
    
    /**
     * 检测紧急修复模式
     */
    private fun detectEmergencyFix(text: String, codeStatsService: CodeStatsService) {
        val emergencyKeywords = listOf(
            "紧急修复", "hotfix", "emergency", "urgent", "critical",
            "线上bug", "生产环境", "prod", "production",
            "回滚", "rollback", "revert", "紧急", "马上", "立刻"
        )
        
        // 检查时间：深夜或非工作时间
        val now = java.time.LocalDateTime.now()
        val isEmergencyTime = now.toLocalTime().isAfter(java.time.LocalTime.of(22, 0)) || 
                             now.toLocalTime().isBefore(java.time.LocalTime.of(6, 0))
        
        if (isEmergencyTime && emergencyKeywords.any { keyword -> 
            text.contains(keyword, ignoreCase = true)
        }) {
            codeStatsService.recordEmergencyFix()
        }
    }
} 
